<?php
declare (strict_types=1);

namespace app\common\logic\category;

use app\common\model\category\Category as CategoryModel;
use app\course\logic\base\Course;
use think\Collection;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;

/**
 * 分类逻辑层
 * @method mhm()
 */
class Category extends CategoryModel
{

    /**
     * 分类树
     * Author   亓官雨树<lucky.max@foxmail.com>
     * Date 2020-04-08
     */
    public function getTree($pid = 0, $field = '*', $type = 0, $mhm_id = 0)
    {
        $this->setCategoryType($type);
        $mhm_id && $map[] = ['mhm_id', '=', $mhm_id];

        $map[]    = ['pid', '=', $pid];
        $category = $this->where($map)->field($field)->order('sort')->select();

        if (!$category->isEmpty()) {
            foreach ($category as $cate) {
                if ($this->hasChildren($cate->id)) {
                    // $cate->hasChildren = $this->hasChildren($cate->id);
                    $cate->child = $this->getTree($cate->id, $field, $type);
                }
            }
        }

        return $category;
    }

    /**
     * 下拉框专用分类树
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-06-12
     * $map = [['id', 'IN', '1,2,4']]
     */
    public function getSelectTree($pid = 0, $type = 0, $map = [])
    {
        $this->setCategoryType($type);
        $where[]  = ['pid', '=', $pid];
        $where    = array_merge($where, $map);
        $category = $this->where($where)->field('id,title,pid')->order('sort')->select();

        if (!$category->isEmpty()) {
            if (!$pid && !$type) $category = $this->appendSplendidCourse($category);
            foreach ($category as $cate) {
                if ($this->hasChildren($cate->id)) {
                    $cate->child = $this->getSelectTree($cate->id, $type, $map);
                }
            }
        }

        return $category;
    }

    /**
     * getTopCategory
     * Author: 亓官雨树 <lucky.max@foxmail.com>
     * Date: 22/12/06
     *
     * @param int   $type
     * @param array $map
     * @return Category[]|array|Collection
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getTopCategory(int $type = 0, array $map = [])
    {
        $this->setCategoryType($type);
        $where[] = ['pid', '=', 0];
        $where   = array_merge($where, $map);

        return $this->where($where)->field('id,title')->order('sort')->select();
    }

    /**
     * 是否有子集
     * Author   亓官雨树<lucky.max@foxmail.com>
     * Date 2020-03-24
     */
    public function hasChildren(int $pid = 0): bool
    {
        return (bool)$this->where('pid', $pid)->find();
    }

    /**
     * 处理分类提交数据
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-06-08
     *
     * @param  [type]                      $category [description]
     */
    public function cateArrToStr($category): string
    {
        $full = '';
        if (count($category)) {
            foreach ($category as $v) {
                $full .= '[' . implode(',', $v) . '],';
            }
            $full = '[' . rtrim($full, ',') . ']';
        }

        return $full;
    }

    /**
     * 分类全路径转分类字符串，如 ,1,2,3,
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-06-16
     */
    public function fullToCate($fullcate): string
    {
        if (is_string($fullcate)) $fullcate = $this->cateStrToArr($fullcate);

        $cates = [];
        foreach ($fullcate as $v) {
            array_push($cates, ...$v);
        }

        return $cates ? ',' . implode(',', array_unique($cates)) . ',' : '';
    }

    /**
     * 处理分类提交数据
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-06-08
     */
    public function cateStrToArr($cate, $path = true)
    {
        $cate = str_replace('[[', '[', $cate);
        $cate = str_replace(']]', ']', $cate);
        $cate = str_replace('],[', ']/,/[', $cate);
        $cate = explode('/,/', $cate);
        if ($path) {
            foreach ($cate as &$c) {
                $c = str_replace('[', '', $c);
                $c = str_replace(']', '', $c);
                $c = explode(',', $c);
                unset($c);
            }
        }

        return $cate;
    }

    /**
     * 全路由分类分组最后一级文字展示
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-06-08
     */
    public function getCateLastText($cate): array
    {
        $data   = [];
        $return = [];
        if (is_array($cate)) {
            foreach ($cate as $v) {
                $data['path'] = $v;
                $data['text'] = $this->withoutGlobalScope()->where('id', end($v))->value('title');
                $return[]     = $data;
            }
        } else if ($cate) {
            $this->cateStrToArr($cate, false);
            foreach ($cate as $v) {
                $data['path'] = $v;
                $arr          = explode(',', str_replace('[', ',', rtrim($v, ']')));
                $data['text'] = $this->withoutGlobalScope()->where('id', end($arr))->value('title');
                $return[]     = $data;
            }
        }

        return $return;
    }

    // 顶级分类
    public function topCategoryByFull($fullcategorypath): array
    {
        $split = $this->cateStrToArr($fullcategorypath, false);
        $top   = [];
        foreach ($split as $str) {
            $str   = str_replace('[', '', $str);
            $str   = str_replace(']', '', $str);
            $top[] = explode(',', $str)[0];
        }

        return array_values(array_unique($top));
    }

    // 接口数据category及fullcategorypath处理
    public function parseFullCateParam($param)
    {
        $param['category']         = is_array($param['category']) ? $param['category'] : json_decode($param['category'], true);
        $param['fullcategorypath'] = $param['category'];
        // if (is_array($param['category'])) {
        //     $param['fullcategorypath'] = $param['category'];
        //     // $param['fullcategorypath'] = $this->cateArrToStr($param['category']);
        // } else {
        //     $param['fullcategorypath'] = json_decode($param['category'], true);
        //     $param['category']         = $this->cateStrToArr($param['category']);
        // }

        return $param;
    }

    /**
     * 获取一级分类
     * Author: 亓官雨树 <lucky.max@foxmail.com>
     * Date: 22/03/11
     *
     * @param int $type
     * @return mixed
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getTopListForSelect(int $type)
    {
        $this->setCategoryType($type);

        return $this->where('pid', 0)->mhm()->field('id,title')->order('sort')->select();
    }

    /**
     * 获取第一个一级分类
     * Author: 亓官雨树 <lucky.max@foxmail.com>
     * Date: 22/03/15
     *
     * @param int $type
     * @return mixed
     */
    public function getFirstTopId(int $type)
    {
        $this->setCategoryType($type);

        return $this->where('pid', 0)->mhm()->order('sort')->value('id');
    }

    public function getTreeStartWithSecondLevel($topId)
    {
        return $this->getSelectTree($topId, 3);
    }

    /**
     * 解析题库名称
     * Author: Martinsun <syh@sunyonghong.com>
     * Date: 2020/11/24
     *
     * @param       $ids
     * @param int   $type
     * @param array $fullcategorypath 分类全路径, 如果传递了该值,则返回array
     * @return string|array
     */
    public function parseTitle($ids, int $type = 0, ?array $fullcategorypath = [])
    {
        if (!$ids) return '';
        $this->setCategoryType($type);
        $cates = $this->whereIn('id', trim($ids, ','))->column('title', 'id');//->buildSql();halt($cates);//

        if ($fullcategorypath) {
            $fullcates = [];
            foreach ($fullcategorypath as $ids) {
                if (is_array($ids)) {
                    $item = [];
                    foreach ($ids as $id) {
                        if (isset($cates[$id])) {
                            $item[] = $cates[$id];
                        }
                    }

                    $fullcates[] = implode('/', $item);
                }
            }

            return $fullcates;
        } else {
            return implode('/', $cates);
        }
    }

    /**
     * cateImplode
     * Author: 亓官雨树 <lucky.max@foxmail.com>
     * Date: 23/07/14
     *
     * @param $category
     * @return string|null
     */
    public function cateImplode($category): ?string
    {
        if (is_string($category) || is_null($category) || !is_array($category)) return $category;

        $cates = [];
        foreach ($category as $v) {
            if (is_array($v)) {
                array_push($cates, ...$v);
            } else {
                $cates[] = $v;
            }
        }

        return count($cates) ? ',' . implode(',', array_unique($cates)) . ',' : '';
    }

    /**
     * appendSplendidCourse
     * Author: 亓官雨树 <lucky.max@foxmail.com>
     * Date: 23/07/14
     *
     * @param $category
     * @return mixed
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    private function appendSplendidCourse($category)
    {
        foreach ($category as $item) {
            $item->splendid_course = app(Course::class)->getRecommendCourseByCate($item->id, 4);
        }

        return $category;
    }
}
